package auto.app.service.impl;

import auto.app.controller.from.AccountPage;
import auto.app.controller.from.AccountRegisterFrom;
import auto.app.controller.from.account.GrantRoleAddFrom;
import auto.app.controller.info.AccountInfo;
import auto.app.controller.info.AccountPageInfo;
import auto.app.controller.info.LoginAccountInfo;
import auto.app.exetion.AccountExetion.AccountSelect;
import auto.app.exetion.MainExection;
import auto.app.model.Account;
import auto.app.dao.AccountDao;
import auto.app.model.AccountRule;
import auto.app.model.Rule;
import auto.app.service.AccountRuleService;
import auto.app.service.AccountService;
import auto.app.service.RuleService;
import auto.app.util.CommonUtil;
import auto.app.util.UserGetAccount;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static auto.app.exetion.MainExetionMessage.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 杨森
 * @since 2022-07-08
 */
@Service
@AllArgsConstructor
public class AccountServiceImpl extends ServiceImpl<AccountDao, Account> implements AccountService, UserDetailsService {

    AccountDao accountDao;
    RuleService ruleService;
    AccountRuleService accountRuleService;

    @SneakyThrows
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        Account account = accountDao.selectOne(new QueryWrapper<Account>().eq("account_Name", s));
        if (account == null) {
            throw new AccountSelect(ACCOUNTSELECTONEERROR.getCode(), ACCOUNTSELECTONEERROR.getMsg());
        }
        AccountInfo accountInfo = new AccountInfo();
        BeanUtils.copyProperties(account, accountInfo);
        return accountInfo;
    }

    @Override
    public Boolean register(AccountRegisterFrom accountRegisterFrom) throws AccountSelect {
        Account account = accountDao.selectOne(new QueryWrapper<Account>().eq("account_Name", accountRegisterFrom.getAccountName()));
        if (account != null) {
            throw new AccountSelect(ACCOUNTSELECTONEEXISTENCE.getCode(), ACCOUNTSELECTONEEXISTENCE.getMsg());
        }
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        accountRegisterFrom.setAccountPass(passwordEncoder.encode(accountRegisterFrom.getAccountPass()));
        Account account1 = new Account();
        BeanUtils.copyProperties(accountRegisterFrom, account1);
        int insert = baseMapper.insert(account1);
        return (insert > 0);
    }

    @Override
    public AccountPageInfo findAllAccount(AccountPage accountPage) {
        AccountPage selectPage = baseMapper.selectPage(accountPage, null);
        AccountPageInfo accountPageInfo = new AccountPageInfo();
        List<Account> records = selectPage.getRecords();
        List<LoginAccountInfo> loginAccountInfos = CommonUtil.copyList(records, LoginAccountInfo.class);
        BeanUtils.copyProperties(selectPage, accountPageInfo);
        accountPageInfo.setRecords(loginAccountInfos);
        return accountPageInfo;
    }

    @Override
    public Boolean grantRoleAdd(GrantRoleAddFrom grantRoleAddFrom) throws MainExection {
        List<Integer> ruleIdList = grantRoleAddFrom.getRuleIdList();
        List<Rule> rules = ruleService.listByIds(ruleIdList);
        //判断所有的角色是否存在
        if (rules.size()!=ruleIdList.size()){
            Map<Integer, String> collect = rules.stream().collect(Collectors.toMap(Rule::getRuleId, Rule::getRuleName));
            for (Integer integer : ruleIdList) {
                if (ObjectUtil.isNull(collect.get(integer))){
                    throw new MainExection(ACCOUNTRULESAVE.getCode(),ACCOUNTRULESAVE.getMsg());
                }
            }
        }
        //新增角色
        //1.移除之前的关联
        boolean remove = accountRuleService.remove(new LambdaQueryWrapper<AccountRule>().eq(AccountRule::getAccountId, UserGetAccount.getAccountId()));
        //2.新增
        ArrayList<AccountRule> accountRuleArrayList=new ArrayList<>();
        for (Integer integer : ruleIdList) {
            accountRuleArrayList.add(AccountRule.builder().accountId(UserGetAccount.getAccountId()).ruleId(integer).build());
        }
        return accountRuleService.saveBatch(accountRuleArrayList);
    }

}
